package com.tedu.api.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 *迭代器:打印集合元素[接口]
 * 集合提供自己一套输出集合元素的方法---迭代器【类似for、增强for]
 * 包位置:java.util
 * Iterator	接口
 * 该接口是集合接口，提供遍历元素的相关操作:问、取、删
 *
 *
 */
public class Collection_iterator {
    @Test
    public void testIterator(){
        //创建集合
        Collection c1=new ArrayList();
        c1.add("one");c1.add("two");c1.add("three");
        c1.add("four");c1.add("five");c1.add("six");
        //iterator()获取一个用于遍历当前集合迭代器的实现类实例
        Iterator it=c1.iterator();
        //理解:拿到集合所有元素，封装迭代器创建对象过程--理解迭代器实例
        //使用Iterator--获取集合的某个元素，规则：问、取、删
        //Iterator接口---hasNext()获取集合元素
        //思考:如果说,300个元素 ----循环 while次数不固定
        while(it.hasNext()) {
            //①问:集合是否有元素
            // 迭代器集合:获取元素 next()获取元素
            String str=(String) it.next();//②取：获取集合元素
            System.out.println("复合迭代器："+str);
            //迭代器是否改变元素的集合内容
            System.out.println(c1);
        }
    }

    /**
     * 试
     * 1普通for---遍历c1集合	集合: size()
     * 语法:for(int i=0;i<c1.size();i++){}
     * 2增强for---遍历c1集合	接收类型:Object
     * 语法:for (object c:c1){}
     * 3Iterator迭代器---集合提供接口     √
     */
    @Test
    public void testCollection() {
        //创建集合
        Collection c1 = new ArrayList();
        c1.add("one");
        c1.add("two");
        c1.add("three");
        c1.add("four");
        c1.add("five");
        c1.add("six");
        //普通for 遍历集合
        //for (int i=0;i<c1.size();i++){
         //   System.out.println("普通for:"+c1[i]);
        //}
        //增强for 遍历集合
        for (Object c:c1){
            System.out.println("增强for："+c);
        }
    }
    /**
     * remove()删除
     * 作用:删除相同的元素数据，提醒:问、取next方法[删
     */
   @Test
    public void testRemove(){
        Collection c=new ArrayList();
        c.add("西游记");c.add("#");c.add("水浒传");
        //需求:通过迭代器删除 #
        Iterator it=c.iterator();
        while(it.hasNext()) {//问:有没有元素
            String str=(String) it.next();    //取:有元素--打印元素
         //   c.remove("#");//Collection中存在remove()
            //删除一定是迭代器
            if("#".equals(str)){//如果#是我们拿到的str元素中#
                it.remove();
            }
        }

       System.out.println("迭代器删除："+c);
}
/**
 *增强for---底层使用Iterator【问、取、删】
 * c.remove("#")是Collection的删除方法，并不是迭代器方法
 * 需求：删除集合中元素“#”
 */
@Test
public void testFor() {
    Collection c = new ArrayList();
    c.add("西游记");
    c.add("#");
    c.add("水浒传");
    for (Object o:c) { //类型 类型引用:集合引用
        if("#".equals(o)){
            c.remove(o);
        }
        System.out.println("删除集合元素："+c);
    }
}
/**
 *E	element	泛型 JDK1.5新特性
 * 结合集合出现，约束集合的使用的类型
 * 泛型的原型:Object，泛型是编译器认可的，JVM虚拟机并不认可
 * 使用泛型是告诉编译器应该把泛型当成Object类型执行，便于编译器检查
 * 类型以及自动造型操作!
 *
 * JDK1.5泛型使用:
 * Collection<类型：基本类型、引用类型、包装类> c
 * =new ArrayList<类型：基本类型、引用类型、包装类>();
 *
 * JDK1.7泛型使用：
 * Collection<类型：基本类型、引用类型、包装类> c
 *  =new ArrayList<>();
 *
 *  泛型：自动推导   通配符：？  表示任意类型
 *  Collection<类型：? extends/super 父类/接口/类 > c
 *   =new ArrayList<>();
 *   优点：保证类型安全，提高代码重用性和灵活性
 */

@Test
public void testType(){
    //泛型：自动推导   通配符：？
    Collection<?> c1 =new ArrayList<>();
    c1.add(null);//结论：并不是匹配所有类型，只能传null 没有意义

    Collection<String> c=new ArrayList<String>();
    c.add("123"); c.add("456"); c.add("789");

    Iterator<String> it=c.iterator();
    while(it.hasNext()) {
        String str = it.next();
        System.out.println(str);

    }
    }
}




//---限定集合传入类型
class Fruit{
    private String name;//成员变量

    public Fruit(String name) {//有参构造器
        this.name = name;
    }

    public String getName() {//方法
        return name;
    }
}
class Apple extends Fruit{
    public Apple(){
        super("苹果");//调用父类有参数构造器，传入name名称
    }
}
class Orange extends Fruit {
    public Orange() {
        super("橘子");//调用父类有参数构造器，传入name名称
    }

    //测试类--泛型上界
    static class TestJob{
        //泛型上界   1.定义方法,制定泛型规则--集合中类型约定为Apple与Orange
        public static void printFruit(Collection<? extends Fruit> fruits){
            //2.增强for循环打印：集合中类型约定为Apple与Orange
            for(Fruit fruit:fruits){
                //3.方法能进入:Apple与Orange--打印名字
                System.out.println(fruit.getName());
            }
        }
        //主方法：测试功能
        public static void main(String[] args) {
            Collection<Apple> apples=new ArrayList<>();
            apples.add(new Apple());//集合对象添加：Apple对象
            Collection<Orange> oranges=new ArrayList<>();
            oranges.add(new Orange());//集合对象添加：Orange对象
            printFruit(apples);//测试打印出苹果
            printFruit(oranges);
            //假设：西瓜
            // Collection<String> strings=new ArrayList<>();
            // strings.add(new String());
            // printFruit(strings);
        }
    }
}


